/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
** 
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
** 
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
** 
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/


//============================================================================
/// \file   DockContainerWidget.cpp
/// \author Uwe Kindler
/// \date   24.02.2017
/// \brief  Implementation of CDockContainerWidget class
//============================================================================


//============================================================================
//                                   INCLUDES
//============================================================================
#include "DockContainerWidget.h"

#include <QEvent>
#include <QList>
#include <QGridLayout>
#include <QPointer>
#include <QVariant>
#include <QDebug>
#include <QXmlStreamWriter>
#include <QAbstractButton>
#include <QLabel>
#include <QTimer>
#include <QMetaObject>
#include <QMetaType>
#include <QApplication>

#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
#include "DockingStateReader.h"
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
#include "ads_globals.h"
#include "DockSplitter.h"
#include "DockWidgetTab.h"
#include "DockAreaTitleBar.h"
#include "DockFocusController.h"
#include "AutoHideDockContainer.h"
#include "AutoHideSideBar.h"
#include "AutoHideTab.h"

#include <functional>
#include <iostream>

#if QT_VERSION < 0x050900
inline char toHexLower(uint value) 
{ 
    return "0123456789abcdef"[value & 0xF]; 
} 
QByteArray qByteArrayToHex(const QByteArray& src, char separator) 
{ 
    if(src.size() == 0) 
        return QByteArray(); 
    const int length = separator ? (src.size() * 3 - 1) : (src.size() * 2); 
    QByteArray hex(length, Qt::Uninitialized); 
    char *hexData = hex.data(); 
    const uchar *data = reinterpret_cast<const uchar *>(src.data()); 
    for (int i = 0, o = 0; i < src.size(); ++i) { 
        hexData[o++] = toHexLower(data[i] >> 4); 
        hexData[o++] = toHexLower(data[i] & 0xf); 
        if ((separator) && (o < length)) 
            hexData[o++] = separator; 
    } 
    return hex; 
} 
#endif 
namespace ads 
{ 
static unsigned int zOrderCounter = 0; 
enum eDropMode 
{ 
    DropModeIntoArea,///< 将窗口部件拖放到停靠区域 
    DropModeIntoContainer,///< 拖放到容器中 
    DropModeInvalid///< 无效模式-不要拖放 
}; 
/** 
 * 将停靠区域ID转换为数组访问的索引 
 */ 
static int areaIdToIndex(DockWidgetArea area) 
{ 
    switch (area) 
    { 
    case LeftDockWidgetArea: return 0; 
    case RightDockWidgetArea: return 1; 
    case TopDockWidgetArea: return 2; 
    case BottomDockWidgetArea: return 3; 
    case CenterDockWidgetArea: return 4; 
    default: 
        return 4; 
    } 
} 
/** 
 * 用于简化将停靠区域插入分裂器的插入小部件的帮助函数 
 */ 
static void insertWidgetIntoSplitter(QSplitter* Splitter, QWidget* widget, bool Append) 
{ 
    if (Append) 
    { 
        Splitter->addWidget(widget); 
    } 
    else 
    { 
        Splitter->insertWidget(0, widget); 
    } 
} 
/** 
 * CDockContainerWidget类的私有数据类（pimpl） 
 */ 
class DockContainerWidgetPrivate 
{ 
public: 
    CDockContainerWidget* _this; 
    QPointer<CDockManager> DockManager; 
    unsigned int zOrderIndex = 0; 
    QList<CDockAreaWidget*> DockAreas; 
    QList<CAutoHideDockContainer*> AutoHideWidgets; 
    QMap<SideBarLocation, CAutoHideSideBar*> SideTabBarWidgets; 
    QGridLayout* Layout = nullptr; 
    CDockSplitter* RootSplitter = nullptr; 
    bool isFloating = false; 
    CDockAreaWidget* LastAddedAreaCache[5]; 
    int VisibleDockAreaCount = -1; 
    CDockAreaWidget* TopLevelDockArea = nullptr; 
    QTimer DelayedAutoHideTimer; 
    CAutoHideTab* DelayedAutoHideTab; 
    bool DelayedAutoHideShow = false; 
    /** 
     * 私有数据构造函数 
     */ 
    DockContainerWidgetPrivate(CDockContainerWidget* _public); 
    /** 
     * 将停靠窗口部件添加到容器中，并返回包含插入的停靠窗口部件的停靠区域 
     */ 
    CDockAreaWidget* addDockWidgetToContainer(DockWidgetArea area, CDockWidget* Dockwidget); 
    /** 
     * 将停靠窗口部件添加到现有的DockWidgetArea中 
     */ 
    CDockAreaWidget* addDockWidgetToDockArea(DockWidgetArea area, CDockWidget* Dockwidget, 
        CDockAreaWidget* TargetDockArea, int Index = -1); 
    /** 
     * 将停靠区域添加到此容器中 
     */ 
    void addDockArea(CDockAreaWidget* NewDockWidget, DockWidgetArea area = CenterDockWidgetArea); 
    /** 
     * 将浮动窗口部件拖放到容器中 
     */ 
    void dropIntoContainer(CFloatingDockContainer* FloatingWidget, DockWidgetArea area); 
    /** 
     * 将浮动窗口部件拖放到自动隐藏侧边栏中 
     */ 
    void dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area); 
    /** 
     * 为放置在部分中心的小部件创建一个新选项卡 
     */ 
    void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget, 
        CDockAreaWidget* TargetArea, int TabIndex = 0); 
    /** 
     * 将浮动窗口部件拖放到停靠区域中 
     */ 
    void dropIntoSection(CFloatingDockContainer* FloatingWidget, 
        CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex = 0); 
    /** 
     * 将Widget参数中给定的停靠窗口部件或停靠区域移动到新的停靠窗口部件区域 
     */ 
    void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area, 
        int TabIndex = 0); 
    /** 
     * 将Widget参数中给定的停靠窗口部件或停靠区域移动到容器中的停靠区域 
     */ 
    void moveToContainer(QWidget* Widgett, DockWidgetArea area); 
    /** 
     * 为放置在部分中心的小部件创建一个新选项卡 
     */ 
    void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea, int TabIndex = 0); 
    /** 
     * 将Widget参数中给定的停靠窗口部件或停靠区域移动到自动隐藏侧边栏区域 
     */ 
    void moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area, int TabIndex = TabDefaultInsertIndex); 
    /** 
     * 将新的停靠区域添加到内部停靠区域列表中 
     */ 
    void addDockAreasToList(const QList<CDockAreaWidget*> NewDockAreas); 
    /** 
     * DockAreas附加的包装函数，确保停靠区域信号正确连接到停靠容器槽 
     */ 
    void appendDockAreas(const QList<CDockAreaWidget*> NewDockAreas); 
    /** 
     * 保存子节点状态 
     */ 
    void saveChildNodesState(QXmlStreamWriter& Stream, QWidget* Widget);

	/**
 * 保存自动隐藏小部件的状态
 */
void saveAutoHideWidgetsState(QXmlStreamWriter& Stream);

/**
 * 恢复子节点的状态
 * \param[in] Stream 包含序列化状态的数据流
 * \param[out] CreatedWidget 从解析数据创建的小部件，如果解析的小部件是一个空的分割器，则为0
 * \param[in] Testing 如果Testing为true，则只解析流数据而不进行任何修改
 */
bool restoreChildNodes(CDockingStateReader& Stream, QWidget*& CreatedWidget, bool Testing);

/**
 * 恢复一个分割器
 * \see restoreChildNodes() 的详细信息
 */
bool restoreSplitter(CDockingStateReader& Stream, QWidget*& CreatedWidget, bool Testing);

/**
 * 恢复一个停靠区域
 * \see restoreChildNodes() 的详细信息
 */
bool restoreDockArea(CDockingStateReader& Stream, QWidget*& CreatedWidget, bool Testing);

/**
 * 恢复一个自动隐藏侧边栏
 */
bool restoreSideBar(CDockingStateReader& Stream, QWidget*& CreatedWidget, bool Testing);

/**
 * 递归转储布局的辅助函数
 */
void dumpRecursive(int level, QWidget* widget);

/**
 * 根据给定的目标位置计算拖放模式
 */
eDropMode getDropMode(const QPoint& TargetPos);

/**
 * 如果尚未初始化，则初始化可见停靠区域计数变量
 */
void initVisibleDockAreaCount()
{
	if (VisibleDockAreaCount > -1)
	{
		return;
	}
	VisibleDockAreaCount = 0;
	for (auto DockArea : DockAreas)
	{
		VisibleDockAreaCount += DockArea->isHidden() ? 0 : 1;
	}
}

/**
 * 可见停靠区域计数变化时调用，当停靠区域被移除、添加或者其视图被切换时
 */
void onVisibleDockAreaCountChanged();

void emitDockAreasRemoved()
{
	onVisibleDockAreaCountChanged();
	Q_EMIT _this->dockAreasRemoved();
}

void emitDockAreasAdded()
{
	onVisibleDockAreaCountChanged();
	Q_EMIT _this->dockAreasAdded();
}

/**
 * 创建新的分割器的辅助函数
 */
CDockSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = nullptr)
{
	CDockSplitter* s = new CDockSplitter(orientation, parent);
	s->setOpaqueResize(CDockManager::testConfigFlag(CDockManager::OpaqueSplitterResize));
	s->setChildrenCollapsible(false);
	return s;
}

/**
 * 如果从代码插入了一个停靠部件，确保分割器的尺寸均匀分布
 */
void adjustSplitterSizesOnInsertion(QSplitter* Splitter, qreal LastRatio = 1.0)
{
	int AreaSize = (Splitter->orientation() == Qt::Horizontal) ? Splitter->width() : Splitter->height();
	auto SplitterSizes = Splitter->sizes();
	qreal TotRatio = SplitterSizes.size() - 1.0 + LastRatio;
	for(int i = 0; i < SplitterSizes.size() -1; i++)
	{
		SplitterSizes[i] = AreaSize / TotRatio;
	}
	SplitterSizes.back() = AreaSize * LastRatio / TotRatio;
	Splitter->setSizes(SplitterSizes);
}

/**
 * 如果存在中心小部件，则强制停靠容器小部件更新分割器的句柄
 */
void updateSplitterHandles(QSplitter* splitter);

/**
 * 如果不存在中心小部件，则小部件随容器一起调整大小
 * 如果存在中心小部件，则围绕中心小部件的小部件不调整其高度或宽度
 */
bool widgetResizesWithContainer(QWidget* widget);

// private slots: ------------------------------------------------------------
void onDockAreaViewToggled(bool Visible)
{
	CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(_this->sender());
	VisibleDockAreaCount += Visible ? 1 : -1;
	onVisibleDockAreaCountChanged();
	Q_EMIT _this->dockAreaViewToggled(DockArea, Visible);
}
}; // struct DockContainerWidgetPrivate
//============================================================================
DockContainerWidgetPrivate::DockContainerWidgetPrivate(CDockContainerWidget* _public) :
	_this(_public)
{
	std::fill(std::begin(LastAddedAreaCache),std::end(LastAddedAreaCache), nullptr);
	DelayedAutoHideTimer.setSingleShot(true);
	DelayedAutoHideTimer.setInterval(500);
	QObject::connect(&DelayedAutoHideTimer, &QTimer::timeout, [this](){
		auto GlobalPos = DelayedAutoHideTab->mapToGlobal(QPoint(0, 0));
		qApp->sendEvent(DelayedAutoHideTab, new QMouseEvent(QEvent::MouseButtonPress,
				QPoint(0, 0), GlobalPos, Qt::LeftButton, {Qt::LeftButton}, Qt::NoModifier));
	});
}
//============================================================================
eDropMode DockContainerWidgetPrivate::getDropMode(const QPoint& TargetPos)
{
	CDockAreaWidget* DockArea = _this->dockAreaAt(TargetPos);
	auto dropArea = InvalidDockWidgetArea;
	auto ContainerDropArea = DockManager->containerOverlay()->dropAreaUnderCursor();
	if (DockArea)
	{
		auto dropOverlay = DockManager->dockAreaOverlay();
		dropOverlay->setAllowedAreas(DockArea->allowedAreas());
		dropArea = dropOverlay->showOverlay(DockArea);
		if (ContainerDropArea != InvalidDockWidgetArea && ContainerDropArea != dropArea)
		{
			dropArea = InvalidDockWidgetArea;
		}
		if (dropArea != InvalidDockWidgetArea)
		{
            ADS_PRINT("Dock Area Drop Content: " << dropArea);
            return DropModeIntoArea;
		}
	}
	// mouse is over container
	if (InvalidDockWidgetArea == dropArea)
	{
		dropArea = ContainerDropArea;
        ADS_PRINT("Container Drop Content: " << dropArea);
		if (dropArea != InvalidDockWidgetArea)
		{
			return DropModeIntoContainer;
		}
	}
	return DropModeInvalid;
}


//============================================================================
// 当可见停靠区域计数发生变化时，更新标题栏按钮的可见性
void DockContainerWidgetPrivate::onVisibleDockAreaCountChanged()
{
    auto TopLevelDockArea = _this->topLevelDockArea();
    if (TopLevelDockArea)
    {
        this->TopLevelDockArea = TopLevelDockArea;
        TopLevelDockArea->updateTitleBarButtonVisibility(true);
    }
    else if (this->TopLevelDockArea)
    {
        this->TopLevelDockArea->updateTitleBarButtonVisibility(false);
        this->TopLevelDockArea = nullptr;
    }
}

//============================================================================
// 将浮动窗口小部件移动到指定的停靠区域
void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* FloatingWidget,
    DockWidgetArea area)
{
    auto InsertParam = internal::dockAreaInsertParameters(area);
    CDockContainerWidget* FloatingDockContainer = FloatingWidget->dockContainer();
    auto NewDockAreas = FloatingDockContainer->findChildren<CDockAreaWidget*>(
        QString(), Qt::FindChildrenRecursively);
    auto Splitter = RootSplitter;

    if (DockAreas.count() <= 1)
    {
        Splitter->setOrientation(InsertParam.orientation());
    }
    else if (Splitter->orientation() != InsertParam.orientation())
    {
        auto NewSplitter = newSplitter(InsertParam.orientation());
        QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
        NewSplitter->addWidget(Splitter);
        updateSplitterHandles(NewSplitter);
        Splitter = NewSplitter;
        delete li;
    }

    // 将浮动窗口小部件的内容插入到此容器中
    auto FloatingSplitter = FloatingDockContainer->rootSplitter();
    if (FloatingSplitter->count() == 1)
    {
        insertWidgetIntoSplitter(Splitter, FloatingSplitter->widget(0), InsertParam.append());
        updateSplitterHandles(Splitter);
    }
    else if (FloatingSplitter->orientation() == InsertParam.orientation())
    {
        int InsertIndex = InsertParam.append() ? Splitter->count() : 0;
        while (FloatingSplitter->count())
        {
            Splitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
            updateSplitterHandles(Splitter);
        }
    }
    else
    {
        insertWidgetIntoSplitter(Splitter, FloatingSplitter, InsertParam.append());
    }

    RootSplitter = Splitter;
    addDockAreasToList(NewDockAreas);

    // 如果分割器不可见，则显示它以显示停靠的小部件
    if (!Splitter->isVisible())
    {
        Splitter->show();
    }

    _this->dumpLayout();
}

//============================================================================
// 将浮动窗口小部件移动到自动隐藏侧边栏
void DockContainerWidgetPrivate::dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget,
    DockWidgetArea area)
{
    auto SideBarLocation = internal::toSideBarLocation(area);
    auto NewDockAreas = FloatingWidget->findChildren<CDockAreaWidget*>(
        QString(), Qt::FindChildrenRecursively);
    int TabIndex = DockManager->containerOverlay()->tabIndexUnderCursor();

    for (auto DockArea : NewDockAreas)
    {
        auto DockWidgets = DockArea->dockWidgets();
        for (auto DockWidget : DockWidgets)
        {
            _this->createAndSetupAutoHideContainer(SideBarLocation, DockWidget, TabIndex++);
        }
    }
}

//============================================================================
// 将浮动窗口小部件移动到停靠区域的中心部分
void DockContainerWidgetPrivate::dropIntoCenterOfSection(
    CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea, int TabIndex)
{
    CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
    auto NewDockWidgets = FloatingContainer->dockWidgets();
    auto TopLevelDockArea = FloatingContainer->topLevelDockArea();
    int NewCurrentIndex = -1;
    TabIndex = qMax(0, TabIndex);

    // 如果浮动窗口小部件只包含一个停靠区域，则当前的停靠小部件也将成为未来在目标区域中的当前停靠小部件
    if (TopLevelDockArea)
    {
        NewCurrentIndex = TopLevelDockArea->currentIndex();
    }

    for (int i = 0; i < NewDockWidgets.count(); ++i)
    {
        CDockWidget* DockWidget = NewDockWidgets[i];
        TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);

        // 如果浮动窗口小部件包含多个可见的停靠区域，则选择第一个可见的打开的停靠小部件作为当前停靠小部件
        if (NewCurrentIndex < 0 && !DockWidget->isClosed())
        {
            NewCurrentIndex = i;
        }
    }

    TargetArea->setCurrentIndex(NewCurrentIndex + TabIndex);
    TargetArea->updateTitleBarVisibility();
    return;
}


// 使下面的代码更易读，必要时添加注释
// 在```后面加上一个新行，然后提供重写的代码

void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex)
{
    // 如果是放在中心，那么所有的停靠窗口都将成为放置区域的选项卡
    if (CenterDockWidgetArea == area)
    {
        moveIntoCenterOfSection(FloatingWidget, TargetArea, TabIndex);
        return;
    }

    // 获取浮动停靠窗口的容器
    CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();

    // 获取插入参数
    auto InsertParam = internal::dockAreaInsertParameters(area);

    // 查找浮动窗口中的所有停靠区域
    auto NewDockAreas = FloatingContainer->findChildren<CDockAreaWidget*>(QString(), Qt::FindChildrenRecursively);

    // 获取目标区域所在的分隔条
    QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetArea);

    // 如果目标区域所在的分隔条不存在，则创建一个新的
    if (!TargetAreaSplitter)
    {
        QSplitter* Splitter = newSplitter(InsertParam.orientation());
        Layout->replaceWidget(TargetArea, Splitter);
        Splitter->addWidget(TargetArea);
        updateSplitterHandles(Splitter);
        TargetAreaSplitter = Splitter;
    }

    // 获取目标区域在分隔条中的索引
    int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);

    // 获取浮动窗口的根分隔条
    auto FloatingSplitter = FloatingContainer->rootSplitter();

    // 如果目标区域所在的分隔条与插入参数的方向相同
    if (TargetAreaSplitter->orientation() == InsertParam.orientation())
    {
        // 获取目标分隔条的大小
        auto Sizes = TargetAreaSplitter->sizes();
        int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();

        // 如果浮动窗口的根分隔条的方向与插入参数的方向不同，并且浮动窗口中有多个停靠区域，则将浮动窗口的根分隔条插入到目标分隔条中
        if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
        {
            TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), FloatingSplitter);
            updateSplitterHandles(TargetAreaSplitter);
        }
        // 否则，将浮动窗口中的所有停靠区域插入到目标分隔条中
        else
        {
            // 如果浮动窗口中只有一个停靠区域，则不需要调整分隔条的大小
            bool AdjustSplitterSizes = (FloatingSplitter->count() == 1);
            int InsertIndex = AreaIndex + InsertParam.insertOffset();
            while (FloatingSplitter->count())
            {
                TargetAreaSplitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
                updateSplitterHandles(TargetAreaSplitter);
            }

            // 如果浮动窗口中有多个停靠区域，则需要调整分隔条的大小
            if (AdjustSplitterSizes)
            {
                int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2;
                Sizes[AreaIndex] = Size;
                Sizes.insert(AreaIndex, Size);
                TargetAreaSplitter->setSizes(Sizes);
            }
        }
    }
    // 如果目标区域所在的分隔条与插入参数的方向不同
    else
    {
        // 创建一个新的分隔条
        QSplitter* NewSplitter = newSplitter(InsertParam.orientation());

        // 获取目标分隔条的大小
        int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();

        // 如果浮动窗口的根分隔条的方向与插入参数的方向不同，并且浮动窗口中有多个停靠区域，则将浮动窗口的根分隔条插入到新的分隔条中
        if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
        {
            NewSplitter->addWidget(FloatingSplitter);
            updateSplitterHandles(NewSplitter);
        }
        // 否则，将浮动窗口中的所有停靠区域插入到新的分隔条中
        else
        {
            // 如果浮动窗口中只有一个停靠区域，则不需要调整分隔条的大小
            bool AdjustSplitterSizes = (FloatingSplitter->count() == 1);
            while (FloatingSplitter->count())
            {
                NewSplitter->addWidget(FloatingSplitter->widget(0));
                updateSplitterHandles(NewSplitter);
            }

            // 如果浮动窗口中有多个停靠区域，则需要调整分隔条的大小
            if (AdjustSplitterSizes)
            {
                int Size = TargetAreaSize / 2;
                NewSplitter->setSizes({Size, Size});
            }
        }

        // 保存插入前的分隔条大小，以防止现有区域缩小
        auto Sizes = TargetAreaSplitter->sizes();

        // 将新的分隔条插入到目标分隔条中
        insertWidgetIntoSplitter(NewSplitter, TargetArea, !InsertParam.append());
        updateSplitterHandles(NewSplitter);

        // 调整分隔条的大小
        TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
        TargetAreaSplitter->setSizes(Sizes);
        updateSplitterHandles(TargetAreaSplitter);
    }

    // 将新的停靠区域添加到列表中
    addDockAreasToList(NewDockAreas);

    // 输出布局信息
    _this->dumpLayout();
}


//============================================================================
// 将窗口或区域移动到目标区域的中心位置
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea, int TabIndex)
{
    auto DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
    auto DroppedArea = qobject_cast<CDockAreaWidget*>(Widget);
    TabIndex = qMax(0, TabIndex);
    
    if (DroppedDockWidget)
    {
        CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget();
        if (OldDockArea == TargetArea)
        {
            return;
        }
        if (OldDockArea)
        {
            OldDockArea->removeDockWidget(DroppedDockWidget);
        }
        TargetArea->insertDockWidget(TabIndex, DroppedDockWidget, true);
    }
    else
    {
        QList<CDockWidget*> NewDockWidgets = DroppedArea->dockWidgets();
        int NewCurrentIndex = DroppedArea->currentIndex();
        for (int i = 0; i < NewDockWidgets.count(); ++i)
        {
            CDockWidget* DockWidget = NewDockWidgets[i];
            TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
        }
        TargetArea->setCurrentIndex(TabIndex + NewCurrentIndex);
        DroppedArea->dockContainer()->removeDockArea(DroppedArea);
        DroppedArea->deleteLater();
    }
    
    TargetArea->updateTitleBarVisibility();
    return;
}

//============================================================================
// 将窗口或区域移动到新的区域
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex)
{
    // 如果移动到中心区域，则将所有停靠窗口变为目标区域的选项卡
    if (CenterDockWidgetArea == area)
    {
        moveIntoCenterOfSection(Widget, TargetArea, TabIndex);
        return;
    }
    
    CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
    CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
    CDockAreaWidget* NewDockArea;
    
    if (DroppedDockWidget)
    {
        NewDockArea = new CDockAreaWidget(DockManager, _this);
        CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget();
        if (OldDockArea)
        {
            OldDockArea->removeDockWidget(DroppedDockWidget);
        }
        NewDockArea->addDockWidget(DroppedDockWidget);
    }
    else
    {
        DroppedDockArea->dockContainer()->removeDockArea(DroppedDockArea);
        NewDockArea = DroppedDockArea;
    }
    
    auto InsertParam = internal::dockAreaInsertParameters(area);
    QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetArea);
    int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
    auto Sizes = TargetAreaSplitter->sizes();
    
    if (TargetAreaSplitter->orientation() == InsertParam.orientation())
    {
        int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();
        TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), NewDockArea);
        updateSplitterHandles(TargetAreaSplitter);
        int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2;
        Sizes[AreaIndex] = Size;
        Sizes.insert(AreaIndex, Size);
    }
    else
    {
        int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();
        QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
        NewSplitter->addWidget(TargetArea);
        insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
        updateSplitterHandles(NewSplitter);
        int Size = TargetAreaSize / 2;
        NewSplitter->setSizes({Size, Size});
        TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
        updateSplitterHandles(TargetAreaSplitter);
    }
    
    TargetAreaSplitter->setSizes(Sizes);
    addDockAreasToList({NewDockArea});
}

//============================================================================
// 将窗口或区域移动到自动隐藏侧边栏
void DockContainerWidgetPrivate::moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area, int TabIndex)
{
    CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
    CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
    auto SideBarLocation = internal::toSideBarLocation(area);
    
    if (DroppedDockWidget)
    {
        if (_this == DroppedDockWidget->dockContainer())
        {
            DroppedDockWidget->setAutoHide(true, SideBarLocation, TabIndex);
        }
        else
        {
            _this->createAndSetupAutoHideContainer(SideBarLocation, DroppedDockWidget, TabIndex);
        }
    }
    else
    {
        if (_this == DroppedDockArea->dockContainer())
        {
            DroppedDockArea->setAutoHide(true, SideBarLocation, TabIndex);
        }
        else
        {
            for (const auto DockWidget : DroppedDockArea->openedDockWidgets())
            {
                if (!DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable))
                {
                    continue;
                }
                _this->createAndSetupAutoHideContainer(SideBarLocation, DockWidget, TabIndex++);
            }
        }
    }
}


//============================================================================
// 更新分隔条的手柄
void DockContainerWidgetPrivate::updateSplitterHandles(QSplitter* splitter)
{
    // 检查中心窗口和分隔条是否为空
    if (!DockManager->centralWidget() || !splitter)
    {
        return;
    }

    // 更新分隔条中每个小部件的拉伸因子
    for (int i = 0; i < splitter->count(); ++i)
    {
        // 如果小部件随容器的大小调整，则将拉伸因子设置为1，否则设置为0
        splitter->setStretchFactor(i, widgetResizesWithContainer(splitter->widget(i)) ? 1 : 0);
    }
}
//============================================================================
// 检查小部件是否随容器的大小调整
bool DockContainerWidgetPrivate::widgetResizesWithContainer(QWidget* widget)
{
    // 检查中心窗口是否为空
    if (!DockManager->centralWidget())
    {
        return true;
    }

    // 检查小部件是否为CDockAreaWidget
    auto Area = qobject_cast<CDockAreaWidget*>(widget);
    if (Area)
    {
        return Area->isCentralWidgetArea();
    }

    // 检查小部件是否为CDockSplitter
    auto innerSplitter = qobject_cast<CDockSplitter*>(widget);
    if (innerSplitter)
    {
        return innerSplitter->isResizingWithContainer();
    }

    return false;
}
//============================================================================
// 将小部件移动到容器中
void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea area)
{
    // 检查Widget是否为CDockWidget
    CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
    // 检查Widget是否为CDockAreaWidget
    CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
    CDockAreaWidget* NewDockArea;

    // 如果Widget是CDockWidget
    if (DroppedDockWidget)
    {
        // 创建一个新的CDockAreaWidget，并将其设置为NewDockArea
        NewDockArea = new CDockAreaWidget(DockManager, _this);
        CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget();
        if (OldDockArea)
        {
            OldDockArea->removeDockWidget(DroppedDockWidget);
        }
        NewDockArea->addDockWidget(DroppedDockWidget);
    }
    else
    {
        // 检查Widget是否被插入到了原来的位置，如果是，则不进行任何操作，如果不是，则将其从原来的容器中移除
        auto Splitter = internal::findParent<CDockSplitter*>(DroppedDockArea);
        auto InsertParam = internal::dockAreaInsertParameters(area);
        if (Splitter == RootSplitter && InsertParam.orientation() == Splitter->orientation())
        {
            if (InsertParam.append() && Splitter->lastWidget() == DroppedDockArea)
            {
                return;
            }
            else if (!InsertParam.append() && Splitter->firstWidget() == DroppedDockArea)
            {
                return;
            }
        }
        DroppedDockArea->dockContainer()->removeDockArea(DroppedDockArea);
        NewDockArea = DroppedDockArea;
    }

    addDockArea(NewDockArea, area);
    LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea;
}
//============================================================================
// 将新的Dock区域添加到列表中
void DockContainerWidgetPrivate::addDockAreasToList(const QList<CDockAreaWidget*> NewDockAreas)
{
    int CountBefore = DockAreas.count();
    int NewAreaCount = NewDockAreas.count();
    appendDockAreas(NewDockAreas);

    // 如果用户放置了一个只包含一个可见Dock区域的浮动窗口，那么它的标题栏按钮TitleBarButtonUndock可能被隐藏了，我们需要确保它可见
    for (auto DockArea : NewDockAreas)
    {
        DockArea->titleBarButton(TitleBarButtonClose)->setVisible(true);
        DockArea->titleBarButton(TitleBarButtonAutoHide)->setVisible(true);
    }

    // 确保Dock区域的标题栏可见。如果Dock区域是浮动窗口中的唯一Dock区域，则标题栏是不可见的。
    if (1 == CountBefore)
    {
        DockAreas.at(0)->updateTitleBarVisibility();
    }
    if (1 == NewAreaCount)
    {
        DockAreas.last()->updateTitleBarVisibility();
    }

    emitDockAreasAdded();
}
//============================================================================
// 将新的Dock区域添加到列表的末尾
void DockContainerWidgetPrivate::appendDockAreas(const QList<CDockAreaWidget*> NewDockAreas)
{
    DockAreas.append(NewDockAreas);
    for (auto DockArea : NewDockAreas)
    {
        QObject::connect(DockArea,
            &CDockAreaWidget::viewToggled,
            _this,
            std::bind(&DockContainerWidgetPrivate::onDockAreaViewToggled, this, std::placeholders::_1));
    }
}


//============================================================================
// 保存子节点的状态到QXmlStreamWriter中
void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidget* Widget)
{
    QSplitter* Splitter = qobject_cast<QSplitter*>(Widget);
    if (Splitter)
    {
        s.writeStartElement("Splitter");
        s.writeAttribute("Orientation", (Splitter->orientation() == Qt::Horizontal) ? "|" : "-");
        s.writeAttribute("Count", QString::number(Splitter->count()));
        ADS_PRINT("NodeSplitter orient: " << Splitter->orientation()
            << " WidgetCont: " << Splitter->count());
        for (int i = 0; i < Splitter->count(); ++i)
        {
            saveChildNodesState(s, Splitter->widget(i));
        }
        s.writeStartElement("Sizes");
        for (auto Size : Splitter->sizes())
        {
            s.writeCharacters(QString::number(Size) + " ");
        }
        s.writeEndElement();
        s.writeEndElement();
    }
    else
    {
        CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Widget);
        if (DockArea)
        {
            DockArea->saveState(s);
        }
    }
}

//============================================================================
// 保存自动隐藏小部件的状态到QXmlStreamWriter中
void DockContainerWidgetPrivate::saveAutoHideWidgetsState(QXmlStreamWriter& s)
{
    for (const auto sideTabBar : SideTabBarWidgets.values())
    {
        if (!sideTabBar->count())
        {
            continue;
        }
        sideTabBar->saveState(s);
    }
}

//============================================================================
// 从保存的状态中恢复一个Splitter
bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s, QWidget*& CreatedWidget, bool Testing)
{
    bool Ok;
    QString OrientationStr = s.attributes().value("Orientation").toString();

    // 检查方向字符串是否正确
    if (!OrientationStr.startsWith("|") && !OrientationStr.startsWith("-"))
    {
        return false;
    }

    // "|" 表示垂直的分隔条，意味着水平的布局
    bool HorizontalSplitter = OrientationStr.startsWith("|");

    // 在版本0中有一个小错误，"|" 表示垂直布局，但实际上应该是水平布局，我们在这里进行修正
    if (s.fileVersion() == 0)
    {
        HorizontalSplitter = !HorizontalSplitter;
    }

    int Orientation = HorizontalSplitter ? Qt::Horizontal : Qt::Vertical;
    int WidgetCount = s.attributes().value("Count").toInt(&Ok);
    if (!Ok)
    {
        return false;
    }
    ADS_PRINT("Restore NodeSplitter Orientation: " <<  Orientation <<
            " WidgetCount: " << WidgetCount);
    QSplitter* Splitter = nullptr;
    if (!Testing)
    {
        Splitter = newSplitter(static_cast<Qt::Orientation>(Orientation));
    }
    bool Visible = false;
    QList<int> Sizes;
    while (s.readNextStartElement())
    {
        QWidget* ChildNode = nullptr;
        bool Result = true;
        if (s.name() == QLatin1String("Splitter"))
        {
            Result = restoreSplitter(s, ChildNode, Testing);
        }
        else if (s.name() == QLatin1String("Area"))
        {
            Result = restoreDockArea(s, ChildNode, Testing);
        }
        else if (s.name() == QLatin1String("Sizes"))
        {
            QString sSizes = s.readElementText().trimmed();
            ADS_PRINT("Sizes: " << sSizes);
            QTextStream TextStream(&sSizes);
            while (!TextStream.atEnd())
            {
                int value;
                TextStream >> value;
                Sizes.append(value);
            }
        }
        else
        {
            s.skipCurrentElement();
        }
        if (!Result)
        {
            return false;
        }
        if (Testing || !ChildNode)
        {
            continue;
        }
        Splitter->addWidget(ChildNode);
        Visible |= ChildNode->isVisibleTo(Splitter);
    }
    if (!Testing)
    {
        updateSplitterHandles(Splitter);
    }
    if (Sizes.count() != WidgetCount)
    {
        return false;
    }
    if (!Testing)
    {
        if (!Splitter->count())
        {
            delete Splitter;
            Splitter = nullptr;
        }
        else
        {
            Splitter->setSizes(Sizes);
            Splitter->setVisible(Visible);
        }
        CreatedWidget = Splitter;
    }
    else
    {
        CreatedWidget = nullptr;
    }
    return true;
}


// 重构后的代码
//============================================================================
// 恢复 Dock 区域
bool DockContainerWidgetPrivate::restoreDockArea(CDockingStateReader& s, QWidget*& CreatedWidget, bool Testing)
{
    CDockAreaWidget* DockArea = nullptr;
    auto Result = CDockAreaWidget::restoreState(s, DockArea, Testing, _this);
    if (Result && DockArea)
    {
        appendDockAreas({DockArea});
    }
    CreatedWidget = DockArea;
    return Result;
}
//============================================================================
// 恢复侧边栏
bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s, QWidget*& CreatedWidget, bool Testing)
{
    Q_UNUSED(CreatedWidget)
    // 如果自动隐藏功能被禁用，则忽略从保存的状态中恢复的自动隐藏侧边栏小部件
    if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
    {
        return true;
    }
    bool Ok;
    auto Area = (ads::SideBarLocation)s.attributes().value("Area").toInt(&Ok);
    if (!Ok)
    {
        return false;
    }
    while (s.readNextStartElement())
    {
        if (s.name() != QLatin1String("Widget"))
        {
            continue;
        }
        auto Name = s.attributes().value("Name");
        if (Name.isEmpty())
        {
            return false;
        }
        bool Ok;
        bool Closed = s.attributes().value("Closed").toInt(&Ok);
        if (!Ok)
        {
            return false;
        }
        int Size = s.attributes().value("Size").toInt(&Ok);
        if (!Ok)
        {
            return false;
        }
        s.skipCurrentElement();
        CDockWidget* DockWidget = DockManager->findDockWidget(Name.toString());
        if (!DockWidget || Testing)
        {
            continue;
        }
        auto SideBar = _this->autoHideSideBar(Area);
        CAutoHideDockContainer* AutoHideContainer;
        if (DockWidget->isAutoHide())
        {
            AutoHideContainer = DockWidget->autoHideDockContainer();
            if (AutoHideContainer->autoHideSideBar() != SideBar)
            {
                SideBar->addAutoHideWidget(AutoHideContainer);
            }
        }
        else
        {
            AutoHideContainer = SideBar->insertDockWidget(-1, DockWidget);
        }
        AutoHideContainer->setSize(Size);
        DockWidget->setProperty(internal::ClosedProperty, Closed);
        DockWidget->setProperty(internal::DirtyProperty, false);
    }
    return true;
}
//============================================================================
// 恢复子节点
bool DockContainerWidgetPrivate::restoreChildNodes(CDockingStateReader& s, QWidget*& CreatedWidget, bool Testing)
{
    bool Result = true;
    while (s.readNextStartElement())
    {
        if (s.name() == QLatin1String("Splitter"))
        {
            Result = restoreSplitter(s, CreatedWidget, Testing);
            ADS_PRINT("Splitter");
        }
        else if (s.name() == QLatin1String("Area"))
        {
            Result = restoreDockArea(s, CreatedWidget, Testing);
            ADS_PRINT("DockAreaWidget");
        }
        else if (s.name() == QLatin1String("SideBar"))
        {
            Result = restoreSideBar(s, CreatedWidget, Testing);
            ADS_PRINT("SideBar");
        }
        else
        {
            s.skipCurrentElement();
            ADS_PRINT("Unknown element");
        }
    }
    return Result;
}
//============================================================================
// 将 Dock 小部件添加到容器中
CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToContainer(DockWidgetArea area, CDockWidget* Dockwidget)
{
    CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
    NewDockArea->addDockWidget(Dockwidget);
    addDockArea(NewDockArea, area);
    NewDockArea->updateTitleBarVisibility();
    LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea;
    return NewDockArea;
}
//============================================================================
// 将 Dock 区域添加到容器中
void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockWidgetArea area)
{
    auto InsertParam = internal::dockAreaInsertParameters(area);
    // 只要在分割器中只有一个 Dock 区域，我们就可以调整其方向
    if (DockAreas.count() <= 1)
    {
        RootSplitter->setOrientation(InsertParam.orientation());
    }
    QSplitter* Splitter = RootSplitter;
    if (Splitter->orientation() == InsertParam.orientation())
    {
        insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
        updateSplitterHandles(Splitter);
        if (Splitter->isHidden())
        {
            Splitter->show();
        }
    }
    else
    {
        auto NewSplitter = newSplitter(InsertParam.orientation());
        if (InsertParam.append())
        {
            QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
            NewSplitter->addWidget(Splitter);
            NewSplitter->addWidget(NewDockArea);
            updateSplitterHandles(NewSplitter);
            delete li;
        }
        else
        {
            NewSplitter->addWidget(NewDockArea);
            QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
            NewSplitter->addWidget(Splitter);
            updateSplitterHandles(NewSplitter);
            delete li;
        }
        RootSplitter = NewSplitter;
    }
    addDockAreasToList({NewDockArea});
}


//============================================================================
void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
{
#if defined(QT_DEBUG)
    QSplitter* Splitter = qobject_cast<QSplitter*>(widget);
    QByteArray buf;
    buf.fill(' ', level * 4);
    if (Splitter)
    {
#ifdef ADS_DEBUG_PRINT
        qDebug("%sSplitter %s v: %s c: %s",
            (const char*)buf,
            (Splitter->orientation() == Qt::Vertical) ? "--" : "|",
             Splitter->isHidden() ? " " : "v",
             QString::number(Splitter->count()).toStdString().c_str());
        std::cout << (const char*)buf << "Splitter "
            << ((Splitter->orientation() == Qt::Vertical) ? "--" : "|") << " "
            << (Splitter->isHidden() ? " " : "v") << " "
            << QString::number(Splitter->count()).toStdString() << std::endl;
#endif
        for (int i = 0; i < Splitter->count(); ++i)
        {
            dumpRecursive(level + 1, Splitter->widget(i));
        }
    }
    else
    {
        CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(widget);
        if (!DockArea)
        {
            return;
        }
#ifdef ADS_DEBUG_PRINT
        qDebug("%sDockArea", (const char*)buf);
        std::cout << (const char*)buf
            << (DockArea->isHidden() ? " " : "v")
            << (DockArea->openDockWidgetsCount() > 0 ? " " : "c")
            << " DockArea " << "[hs: " << DockArea->sizePolicy().horizontalStretch() << ", vs: " <<  DockArea->sizePolicy().verticalStretch() << "]" << std::endl;
        buf.fill(' ', (level + 1) * 4);
        for (int i = 0; i < DockArea->dockWidgetsCount(); ++i)
        {
            std::cout << (const char*)buf << (i == DockArea->currentIndex() ? "*" : " ");
            CDockWidget* DockWidget = DockArea->dockWidget(i);
            std::cout << (DockWidget->isHidden() ? " " : "v");
            std::cout << (DockWidget->isClosed() ? "c" : " ") << " ";
            std::cout << DockWidget->windowTitle().toStdString() << std::endl;
        }
#endif
    }
#else
    Q_UNUSED(level);
    Q_UNUSED(widget);
#endif
}
//============================================================================
CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetArea area,
    CDockWidget* Dockwidget, CDockAreaWidget* TargetDockArea, int Index)
{
    if (CenterDockWidgetArea == area)
    {
        TargetDockArea->insertDockWidget(Index, Dockwidget);
        TargetDockArea->updateTitleBarVisibility();
        return TargetDockArea;
    }
    CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
    NewDockArea->addDockWidget(Dockwidget);
    auto InsertParam = internal::dockAreaInsertParameters(area);
    QSplitter* TargetAreaSplitter = internal::findParent<QSplitter*>(TargetDockArea);
    int index = TargetAreaSplitter ->indexOf(TargetDockArea);
    if (TargetAreaSplitter->orientation() == InsertParam.orientation())
    {
        ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()");
        TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea);
        updateSplitterHandles(TargetAreaSplitter);
        // do nothing, if flag is not enabled
        if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
        {
            adjustSplitterSizesOnInsertion(TargetAreaSplitter);
        }
    }
    else
    {
        ADS_PRINT("TargetAreaSplitter->orientation() != InsertParam.orientation()");
        auto TargetAreaSizes = TargetAreaSplitter->sizes();
        QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
        NewSplitter->addWidget(TargetDockArea);
        insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
        updateSplitterHandles(NewSplitter);
        TargetAreaSplitter->insertWidget(index, NewSplitter);
        updateSplitterHandles(TargetAreaSplitter);
        if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
        {
            TargetAreaSplitter->setSizes(TargetAreaSizes);
            adjustSplitterSizesOnInsertion(NewSplitter);
        }
    }
    addDockAreasToList({NewDockArea});
    return NewDockArea;
}
//============================================================================
// CDockContainerWidget 构造函数
CDockContainerWidget::CDockContainerWidget(CDockManager* DockManager, QWidget *parent) :
    QFrame(parent),
    d(new DockContainerWidgetPrivate(this))
{
    d->DockManager = DockManager;
    d->isFloating = floatingWidget() != nullptr;
    d->Layout = new QGridLayout();
    d->Layout->setContentsMargins(0, 0, 0, 0);
    d->Layout->setSpacing(0);
    d->Layout->setColumnStretch(1, 1);
    d->Layout->setRowStretch(1, 1);
    setLayout(d->Layout);

    // 函数 d->newSplitter() 访问了 dock 管理器中的配置标志，这需要一个正确构造的 dock 管理器。
    // 如果此 dock 容器就是 dock 管理器，则它尚未正确构造，因为在 DockManager 的私有类的构造函数之前调用了此基类构造函数。
    if (DockManager != this)
    {
        d->DockManager->registerDockContainer(this);
        createRootSplitter(); // 创建根分割器
        createSideTabBarWidgets(); // 创建侧边标签栏小部件
    }
}
//============================================================================

// CDockContainerWidget 析构函数
CDockContainerWidget::~CDockContainerWidget()
{
    if (d->DockManager)
    {
        d->DockManager->removeDockContainer(this);
    }
    delete d;
}
//============================================================================

// 将 Dock 小部件添加到 Dock 区域
CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
    CDockAreaWidget* DockAreaWidget, int Index)
{
    auto TopLevelDockWidget = topLevelDockWidget(); // 获取顶级 Dock 小部件
    CDockAreaWidget* OldDockArea = Dockwidget->dockAreaWidget(); // 获取原来所在的 Dock 区域

    // 从原来的 Dock 区域中移除 Dock 小部件
    if (OldDockArea)
    {
        OldDockArea->removeDockWidget(Dockwidget);
    }

    // 设置 Dock 小部件的 Dock 管理器
    Dockwidget->setDockManager(d->DockManager);

    CDockAreaWidget* DockArea;
    if (DockAreaWidget)
    {
        DockArea = d->addDockWidgetToDockArea(area, Dockwidget, DockAreaWidget, Index); // 将 Dock 小部件添加到指定的 Dock 区域
    }
    else
    {
        DockArea = d->addDockWidgetToContainer(area, Dockwidget); // 将 Dock 小部件添加到容器中
    }

    // 检查 Dock 容器是否有顶级 Dock 小部件
    if (TopLevelDockWidget)
    {
        auto NewTopLevelDockWidget = topLevelDockWidget();

        // 如果容器只包含一个可见的 Dock 小部件，那么我们需要为该小部件发出顶级事件，因为它不再是唯一可见的停靠小部件
        if (!NewTopLevelDockWidget)
        {
            CDockWidget::emitTopLevelEventForWidget(TopLevelDockWidget, false);
        }
    }

    return DockArea;
}


//============================================================================
// 创建并设置自动隐藏容器
CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget, int TabIndex)
{
    // 检查自动隐藏功能是否启用
    if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
    {
        Q_ASSERT_X(false, "CDockContainerWidget::createAndInitializeDockWidgetOverlayContainer", "Requested area does not exist in config");
        return nullptr;
    }
    
    // 如果DockWidget的dockManager与当前容器的dockManager不一致，需要设置一致
    if (d->DockManager != DockWidget->dockManager())
    {
        DockWidget->setDockManager(d->DockManager); // 自动隐藏容器需要一个有效的dockManager
    }
    
    // 将DockWidget插入到指定位置的自动隐藏侧边栏中
    return autoHideSideBar(area)->insertDockWidget(TabIndex, DockWidget);
}
//============================================================================

// 移除DockWidget
void CDockContainerWidget::removeDockWidget(CDockWidget* Dockwidget)
{
    CDockAreaWidget* Area = Dockwidget->dockAreaWidget();
    if (Area)
    {
        Area->removeDockWidget(Dockwidget);
    }
}
//============================================================================

// 获取zOrderIndex
unsigned int CDockContainerWidget::zOrderIndex() const
{
    return d->zOrderIndex;
}
//============================================================================

// 判断当前容器是否在Other容器之前
bool CDockContainerWidget::isInFrontOf(CDockContainerWidget* Other) const
{
    return this->zOrderIndex() > Other->zOrderIndex();
}
//============================================================================

// 处理事件
bool CDockContainerWidget::event(QEvent *e)
{
    bool Result = QWidget::event(e);
    
    // 窗口激活事件
    if (e->type() == QEvent::WindowActivate)
    {
        d->zOrderIndex = ++zOrderCounter;
    }
    // 显示事件且zOrderIndex为0
    else if (e->type() == QEvent::Show && !d->zOrderIndex)
    {
        d->zOrderIndex = ++zOrderCounter;
    }
    
    return Result;
}
//============================================================================

// 获取所有自动隐藏的容器
QList<CAutoHideDockContainer*> CDockContainerWidget::autoHideWidgets() const
{
    return d->AutoHideWidgets;
}
//============================================================================

// 添加DockArea
void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget, DockWidgetArea area)
{
    CDockContainerWidget* Container = DockAreaWidget->dockContainer();
    if (Container && Container != this)
    {
        Container->removeDockArea(DockAreaWidget);
    }
    
    d->addDockArea(DockAreaWidget, area);
}


// 使下面的代码更易读，必要时添加注释
void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
{
    ADS_PRINT("CDockContainerWidget::removeDockArea");

    // 如果是自动隐藏区域，则不需要做太多事情
    if (area->isAutoHide())
    {
        area->setAutoHideDockContainer(nullptr);
        return;
    }

    // 断开连接并从 DockAreas 中移除区域
    area->disconnect(this);
    d->DockAreas.removeAll(area);

    // 查找父级分隔器
    CDockSplitter* Splitter = internal::findParent<CDockSplitter*>(area);

    // 将区域从父级分隔器中移除，并递归隐藏父级分隔器树，如果它没有可见内容
    area->setParent(nullptr);
    internal::hideEmptyParentSplitters(Splitter);

    // 从缓存区域中移除此区域
    auto p = std::find(std::begin(d->LastAddedAreaCache), std::end(d->LastAddedAreaCache), area);
    if (p != std::end(d->LastAddedAreaCache))
    {
        *p = nullptr;
    }

    // 如果分隔器中有多个小部件，则完成并离开
    if (Splitter->count() > 1)
    {
        goto emitAndExit;
    }

    // 如果这是 RootSplitter，则需要删除空分隔器，以避免太多的空分隔器
    if (Splitter == d->RootSplitter)
    {
        ADS_PRINT("Removed from RootSplitter");

        // 如果分隔器为空，则完成
        if (!Splitter->count())
        {
            Splitter->hide();
            goto emitAndExit;
        }

        // 如果分隔器的唯一内容小部件不是分隔器，则完成
        QWidget* widget = Splitter->widget(0);
        auto ChildSplitter = qobject_cast<CDockSplitter*>(widget);
        if (!ChildSplitter)
        {
            goto emitAndExit;
        }

        // 用 ChildSplitter 替换多余的 RootSplitter
        ChildSplitter->setParent(nullptr);
        QLayoutItem* li = d->Layout->replaceWidget(Splitter, ChildSplitter);
        d->RootSplitter = ChildSplitter;
        delete li;
        ADS_PRINT("RootSplitter replaced by child splitter");
    }
    else if (Splitter->count() == 1)
    {
        ADS_PRINT("Replacing splitter with content");

        // 用内容替换分隔器
        QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
        auto Sizes = ParentSplitter->sizes();
        QWidget* widget = Splitter->widget(0);
        widget->setParent(this);
        internal::replaceSplitterWidget(ParentSplitter, Splitter, widget);
        ParentSplitter->setSizes(Sizes);
    }

    // 删除分隔器
    delete Splitter;
    Splitter = nullptr;

emitAndExit:
    // 更新分隔器句柄
    updateSplitterHandles(Splitter);

    // 如果只有一个可见的停靠窗口，则更新停靠窗口的标题栏可见性
    CDockWidget* TopLevelWidget = topLevelDockWidget();
    CDockWidget::emitTopLevelEventForWidget(TopLevelWidget, true);

    // 输出布局信息
    dumpLayout();

    // 发出 DockAreasRemoved 信号
    d->emitDockAreasRemoved();
}


//============================================================================
// 根据给定的全局位置返回对应的 Dock 区域
CDockAreaWidget* CDockContainerWidget::dockAreaAt(const QPoint& GlobalPos) const
{
    for (const auto& DockArea : d->DockAreas)
    {
        if (DockArea->isVisible() && DockArea->rect().contains(DockArea->mapFromGlobal(GlobalPos)))
        {
            return DockArea;
        }
    }
    return nullptr;
}

//============================================================================
// 根据索引返回对应的 Dock 区域
CDockAreaWidget* CDockContainerWidget::dockArea(int Index) const
{
    return (Index < dockAreaCount()) ? d->DockAreas[Index] : nullptr;
}

//============================================================================
// 检查 Dock 容器是否浮动
bool CDockContainerWidget::isFloating() const
{
    return d->isFloating;
}

//============================================================================
// 返回 Dock 区域的数量
int CDockContainerWidget::dockAreaCount() const
{
    return d->DockAreas.count();
}

//============================================================================
// 返回可见的 Dock 区域的数量
int CDockContainerWidget::visibleDockAreaCount() const
{
    int Result = 0;
    for (auto DockArea : d->DockAreas)
    {
        Result += DockArea->isHidden() ? 0 : 1;
    }
    return Result;
    // TODO：缓存或预计算这个值以提高速度，因为在移动浮动小部件时会使用到它
    // return d->visibleDockAreaCount();
}


//============================================================================
void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget,
    const QPoint& TargetPos)
{
    // 打印日志
    ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
    
    // 获取被拖动的浮动窗口中的顶级窗口
    CDockWidget* SingleDroppedDockWidget = FloatingWidget->topLevelDockWidget();
    
    // 获取当前窗口中的顶级窗口
    CDockWidget* SingleDockWidget = topLevelDockWidget();
    
    // 初始化变量
    auto dropArea = InvalidDockWidgetArea;
    auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
    bool Dropped = false;
    
    // 获取鼠标位置所在的Dock区域
    CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
    
    // 如果鼠标位置在Dock区域上
    if (DockArea)
    {
        auto dropOverlay = d->DockManager->dockAreaOverlay();
        dropOverlay->setAllowedAreas(DockArea->allowedAreas());
        dropArea = dropOverlay->showOverlay(DockArea);
        
        // 如果鼠标位置下方有其他Dock区域，并且不是当前显示的区域
        if (ContainerDropArea != InvalidDockWidgetArea &&
            ContainerDropArea != dropArea)
        {
            dropArea = InvalidDockWidgetArea;
        }
        
        // 如果鼠标位置下方有有效的Dock区域
        if (dropArea != InvalidDockWidgetArea)
        {
            // 打印日志
            ADS_PRINT("Dock Area Drop Content: " << dropArea);
            
            // 获取鼠标位置下方的Tab索引
            int TabIndex = d->DockManager->dockAreaOverlay()->tabIndexUnderCursor();
            
            // 在指定的位置插入浮动窗口
            d->dropIntoSection(FloatingWidget, DockArea, dropArea, TabIndex);
            
            Dropped = true;
        }
    }
    
    // 如果鼠标位置在容器上或自动隐藏侧边栏上
    if (InvalidDockWidgetArea == dropArea && InvalidDockWidgetArea != ContainerDropArea)
    {
        if (internal::isSideBarArea(ContainerDropArea))
        {
            // 打印日志
            ADS_PRINT("Container Drop Content: " << ContainerDropArea);
            
            // 将浮动窗口插入自动隐藏侧边栏
            d->dropIntoAutoHideSideBar(FloatingWidget, ContainerDropArea);
        }
        else
        {
            // 打印日志
            ADS_PRINT("Container Drop Content: " << ContainerDropArea);
            
            // 将浮动窗口插入容器中
            d->dropIntoContainer(FloatingWidget, ContainerDropArea);
        }
        
        Dropped = true;
    }
    
    // 将自动隐藏窗口从浮动窗口中移动到当前窗口中
    for (auto AutohideWidget : FloatingWidget->dockContainer()->autoHideWidgets())
    {
        auto SideBar = autoHideSideBar(AutohideWidget->sideBarLocation());
        SideBar->addAutoHideWidget(AutohideWidget);
    }
    
    // 如果有窗口被成功拖动
    if (Dropped)
    {
        // 修复问题 https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351
        FloatingWidget->hideAndDeleteLater();
        
        // 如果拖动的浮动窗口中只有一个顶级窗口，则发出顶级窗口事件，将其从浮动状态转为停靠状态
        CDockWidget::emitTopLevelEventForWidget(SingleDroppedDockWidget, false);
        
        // 如果拖动前有一个顶级窗口，则不再是顶级窗口
        CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);
    }
    
    // 激活窗口
    window()->activateWindow();
    
    // 如果有被拖动的顶级窗口
    if (SingleDroppedDockWidget)
    {
        // 通知Dock管理器顶级窗口或区域已被移动
        d->DockManager->notifyWidgetOrAreaRelocation(SingleDroppedDockWidget);
    }
    
    // 通知Dock管理器浮动窗口已被拖动
    d->DockManager->notifyFloatingWidgetDrop(FloatingWidget);
}


//============================================================================

// 使代码更易读
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
	int TabIndex)
{
    // 获取顶级的dock widget
    CDockWidget* SingleDockWidget = topLevelDockWidget();

    // 如果存在目标区域窗口，则将小部件移动到该区域
	if (TargetAreaWidget)
	{
		d->moveToNewSection(Widget, TargetAreaWidget, DropArea, TabIndex);
	}
    // 如果是侧边栏区域，则将小部件移动到自动隐藏侧边栏
	else if (internal::isSideBarArea(DropArea))
	{
		d->moveToAutoHideSideBar(Widget, DropArea, TabIndex);
	}
    // 否则将小部件移动到容器中
	else
	{
		d->moveToContainer(Widget, DropArea);
	}

	// 如果在放置之前存在顶级小部件，则它不再是顶级小部件
	CDockWidget::emitTopLevelEventForWidget(SingleDockWidget, false);

	// 激活窗口
	window()->activateWindow();

	// 通知dock manager小部件或区域已重新定位
	d->DockManager->notifyWidgetOrAreaRelocation(Widget);
}

//============================================================================

// 使代码更易读
QList<CDockAreaWidget*> CDockContainerWidget::openedDockAreas() const
{
	QList<CDockAreaWidget*> Result;

	// 遍历所有的dock区域
	for (auto DockArea : d->DockAreas)
	{
		// 如果dock区域没有被隐藏，则将其添加到结果列表中
		if (!DockArea->isHidden())
		{
			Result.append(DockArea);
		}
	}

	return Result;
}

//============================================================================

// 使代码更易读
QList<CDockWidget*> CDockContainerWidget::openedDockWidgets() const
{
	QList<CDockWidget*> DockWidgetList;

	// 遍历所有的dock区域
	for (auto DockArea : d->DockAreas)
	{
		// 如果dock区域没有被隐藏，则将其打开的dock小部件添加到列表中
		if (!DockArea->isHidden())
		{
			DockWidgetList.append(DockArea->openedDockWidgets());
		}
	}

	return DockWidgetList;
}

//============================================================================

// 使代码更易读
bool CDockContainerWidget::hasOpenDockAreas() const
{
	// 遍历所有的dock区域
	for (auto DockArea : d->DockAreas)
	{
		// 如果dock区域没有被隐藏，则返回true
		if (!DockArea->isHidden())
		{
			return true;
		}
	}

	return false;
}

//============================================================================

// 使代码更易读
void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
{
    ADS_PRINT("CDockContainerWidget::saveState isFloating " << isFloating());

    // 写入容器元素
	s.writeStartElement("Container");
	s.writeAttribute("Floating", QString::number(isFloating() ? 1 : 0));

	// 如果是浮动窗口
	if (isFloating())
	{
		CFloatingDockContainer* FloatingWidget = floatingWidget();
		QByteArray Geometry = FloatingWidget->saveGeometry();

        // 写入浮动窗口的几何信息
#if QT_VERSION < 0x050900
        s.writeTextElement("Geometry", qByteArrayToHex(Geometry, ' '));
#else
		s.writeTextElement("Geometry", Geometry.toHex(' '));
#endif
	}

	// 保存子节点的状态
	d->saveChildNodesState(s, d->RootSplitter);

	// 保存自动隐藏窗口的状态
	d->saveAutoHideWidgetsState(s);

	// 写入结束标签
	s.writeEndElement();
}


//============================================================================

// 恢复 Dock 容器小部件的状态
bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
{
    bool IsFloating = s.attributes().value("Floating").toInt(); // 从状态读取器中获取 "Floating" 属性的值
    ADS_PRINT("恢复 CDockContainerWidget 的浮动状态：" << IsFloating); // 打印 IsFloating 的值
    QWidget* NewRootSplitter {}; // 初始化 NewRootSplitter 为 nullptr

    // 如果不是测试模式，重置一些变量
    if (!Testing)
    {
        d->VisibleDockAreaCount = -1; // 使 dock 区域计数无效
        d->DockAreas.clear(); // 清空 dock 区域列表
        std::fill(std::begin(d->LastAddedAreaCache),std::end(d->LastAddedAreaCache), nullptr); // 将 LastAddedAreaCache 设置为 nullptr
    }

    // 如果 IsFloating 为 true，则恢复浮动窗口小部件
    if (IsFloating)
    {
        ADS_PRINT("恢复浮动窗口小部件");
        if (!s.readNextStartElement() || s.name() != QLatin1String("Geometry"))
        {
            return false;
        }
        QByteArray GeometryString = s.readElementText(CDockingStateReader::ErrorOnUnexpectedElement).toLocal8Bit();
        QByteArray Geometry = QByteArray::fromHex(GeometryString);
        if (Geometry.isEmpty())
        {
            return false;
        }
        if (!Testing)
        {
            CFloatingDockContainer* FloatingWidget = floatingWidget();
            if (FloatingWidget)
            {
                FloatingWidget->restoreGeometry(Geometry);
            }
        }
    }

    // 恢复子节点
    if (!d->restoreChildNodes(s, NewRootSplitter, Testing))
    {
        return false;
    }

    // 如果根分割器为空，则创建一个空的根分割器
    if (Testing)
    {
        return true;
    }
    if (!NewRootSplitter)
    {
        NewRootSplitter = d->newSplitter(Qt::Horizontal);
    }

    // 用新的根分割器替换旧的根分割器
    d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
    auto OldRoot = d->RootSplitter;
    d->RootSplitter = qobject_cast<CDockSplitter*>(NewRootSplitter);
    OldRoot->deleteLater();

    return true;
}

//============================================================================

// 获取根分割器
QSplitter* CDockContainerWidget::rootSplitter() const
{
    return d->RootSplitter;
}

//============================================================================

// 创建根分割器
void CDockContainerWidget::createRootSplitter()
{
    if (d->RootSplitter)
    {
        return;
    }
    d->RootSplitter = d->newSplitter(Qt::Horizontal);
    d->Layout->addWidget(d->RootSplitter, 1, 1);
}

//============================================================================

// 创建侧边标签栏小部件
void CDockContainerWidget::createSideTabBarWidgets()
{
    if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
    {
        return;
    }

    // 为每个侧边创建标签栏小部件
    {
        auto Area = SideBarLocation::SideBarLeft;
        d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
        d->Layout->addWidget(d->SideTabBarWidgets[Area], 1, 0);
    }
    {
        auto Area = SideBarLocation::SideBarRight;
        d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
        d->Layout->addWidget(d->SideTabBarWidgets[Area], 1, 2);
    }
    {
        auto Area = SideBarLocation::SideBarBottom;
        d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
        d->Layout->addWidget(d->SideTabBarWidgets[Area], 2, 1);
    }
    {
        auto Area = SideBarLocation::SideBarTop;
        d->SideTabBarWidgets[Area] = new CAutoHideSideBar(this, Area);
        d->Layout->addWidget(d->SideTabBarWidgets[Area], 0, 1);
    }
}


//============================================================================
// 打印布局信息，用于调试目的
void CDockContainerWidget::dumpLayout()
{
#if (ADS_DEBUG_LEVEL > 0)
    qDebug("\n\nDumping layout --------------------------");
    std::cout << "\n\nDumping layout --------------------------" << std::endl;
    d->dumpRecursive(0, d->RootSplitter);
    qDebug("--------------------------\n\n");
    std::cout << "--------------------------\n\n" << std::endl;
#endif
}
//============================================================================
// 获取指定区域最后添加的 Dock 区域小部件
CDockAreaWidget* CDockContainerWidget::lastAddedDockAreaWidget(DockWidgetArea area) const
{
    return d->LastAddedAreaCache[areaIdToIndex(area)];
}
//============================================================================
// 检查是否存在顶级 Dock 小部件
bool CDockContainerWidget::hasTopLevelDockWidget() const
{
    auto DockAreas = openedDockAreas();
    if (DockAreas.count() != 1)
    {
        return false;
    }
    return DockAreas[0]->openDockWidgetsCount() == 1;
}
//============================================================================
// 获取顶级 Dock 小部件
CDockWidget* CDockContainerWidget::topLevelDockWidget() const
{
    auto TopLevelDockArea = topLevelDockArea();
    if (!TopLevelDockArea)
    {
        return nullptr;
    }
    auto DockWidgets = TopLevelDockArea->openedDockWidgets();
    if (DockWidgets.count() != 1)
    {
        return nullptr;
    }
    return DockWidgets[0];
}


//============================================================================
// 返回顶级的停靠区域
CDockAreaWidget* CDockContainerWidget::topLevelDockArea() const
{
    auto DockAreas = openedDockAreas();
    // 如果有多个停靠区域，返回nullptr
    if (DockAreas.count() != 1)
    {
        return nullptr;
    }
    // 返回第一个停靠区域
    return DockAreas[0];
}
//============================================================================
// 返回一个包含所有停靠小部件的列表
QList<CDockWidget*> CDockContainerWidget::dockWidgets() const
{
    QList<CDockWidget*> Result;
    // 遍历每个停靠区域
    for (const auto DockArea : d->DockAreas)
    {
        // 将每个停靠区域的停靠小部件添加到结果列表中
        Result.append(DockArea->dockWidgets());
    }
    return Result;
}
//============================================================================
// 更新分割器的手柄
void CDockContainerWidget::updateSplitterHandles(QSplitter* splitter)
{
    d->updateSplitterHandles(splitter);
}
//============================================================================
// 注册自动隐藏小部件
void CDockContainerWidget::registerAutoHideWidget(CAutoHideDockContainer* AutohideWidget)
{
    // 将自动隐藏小部件添加到列表中
    d->AutoHideWidgets.append(AutohideWidget);
    // 发射信号，通知自动隐藏小部件已创建
    Q_EMIT autoHideWidgetCreated(AutohideWidget);
    // 打印自动隐藏小部件的数量
    ADS_PRINT("d->AutoHideWidgets.count() " << d->AutoHideWidgets.count());
}
//============================================================================
// 移除自动隐藏小部件
void CDockContainerWidget::removeAutoHideWidget(CAutoHideDockContainer* AutohideWidget)
{
    // 从列表中移除自动隐藏小部件
    d->AutoHideWidgets.removeAll(AutohideWidget);
}
//============================================================================
// 返回停靠容器小部件的特性
CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const
{
    CDockWidget::DockWidgetFeatures Features(CDockWidget::AllDockWidgetFeatures);
    // 遍历每个停靠区域
    for (const auto DockArea : d->DockAreas)
    {
        // 获取每个停靠区域的特性，并更新停靠容器小部件的特性
        Features &= DockArea->features();
    }
    return Features;
}


//============================================================================
// 返回 dock 容器的浮动窗口
CFloatingDockContainer* CDockContainerWidget::floatingWidget() const
{
    return internal::findParent<CFloatingDockContainer*>(this);
}
//============================================================================
// 关闭除指定保持打开区域外的所有其他区域
void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
{
    for (const auto DockArea : d->DockAreas)
    {
        // 跳过保持打开区域
        if (DockArea == KeepOpenArea)
        {
            continue;
        }
        // 跳过不可关闭的区域
        if (!DockArea->features(BitwiseAnd).testFlag(CDockWidget::DockWidgetClosable))
        {
            continue;
        }
        // 跳过具有自定义关闭处理的区域
        if (DockArea->features(BitwiseOr).testFlag(CDockWidget::CustomCloseHandling))
        {
            continue;
        }
        // 关闭区域
        DockArea->closeArea();
    }
}
//============================================================================
// 返回指定位置的自动隐藏侧边栏
CAutoHideSideBar* CDockContainerWidget::autoHideSideBar(SideBarLocation area) const
{
    return d->SideTabBarWidgets[area];
}
//============================================================================
// 返回 dock 容器的内容矩形
QRect CDockContainerWidget::contentRect() const
{
    if (!d->RootSplitter)
    {
        return QRect();
    }
    if (d->RootSplitter->hasVisibleContent())
    {
        return d->RootSplitter->geometry();
    }
    else
    {
        auto ContentRect = this->rect();
        ContentRect.adjust(
            autoHideSideBar(SideBarLeft)->sizeHint().width(),
            autoHideSideBar(SideBarTop)->sizeHint().height(),
            -autoHideSideBar(SideBarRight)->sizeHint().width(),
            -autoHideSideBar(SideBarBottom)->sizeHint().height());
        return ContentRect;
    }
}
//===========================================================================
// 返回 dock 容器的全局内容矩形
QRect CDockContainerWidget::contentRectGlobal() const
{
    if (!d->RootSplitter)
    {
        return QRect();
    }
    return internal::globalGeometry(d->RootSplitter);
}
//===========================================================================
// 返回 dock 容器的 dock 管理器
CDockManager* CDockContainerWidget::dockManager() const
{
    return d->DockManager;
}

//===========================================================================
void CDockContainerWidget::handleAutoHideWidgetEvent(QEvent* e, QWidget* w)
{
    // 检查是否启用了鼠标悬停显示自动隐藏窗口的配置选项
    if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideShowOnMouseOver))
    {
        return;
    }

    // 检查是否正在恢复状态
    if (dockManager()->isRestoringState())
    {
        return;
    }

    auto AutoHideTab = qobject_cast<CAutoHideTab*>(w);
    if (AutoHideTab)
    {
        switch (e->type())
        {
        case QEvent::Enter:
            // 如果自动隐藏窗口不可见，则设置延迟显示
            if (!AutoHideTab->dockWidget()->isVisible())
            {
                d->DelayedAutoHideTab = AutoHideTab;
                d->DelayedAutoHideShow = true;
                d->DelayedAutoHideTimer.start();
            }
            else
            {
                d->DelayedAutoHideTimer.stop();
            }
            break;
        case QEvent::MouseButtonPress:
            // 鼠标按下时停止延迟显示
            d->DelayedAutoHideTimer.stop();
            break;
        case QEvent::Leave:
            // 如果自动隐藏窗口可见，则设置延迟隐藏
            if (AutoHideTab->dockWidget()->isVisible())
            {
                d->DelayedAutoHideTab = AutoHideTab;
                d->DelayedAutoHideShow = false;
                d->DelayedAutoHideTimer.start();
            }
            else
            {
                d->DelayedAutoHideTimer.stop();
            }
            break;
        default:
            break;
        }
        return;
    }

    auto AutoHideContainer = qobject_cast<CAutoHideDockContainer*>(w);
    if (AutoHideContainer)
    {
        switch (e->type())
        {
        case QEvent::Enter:
        case QEvent::Hide:
            // 鼠标进入或隐藏时停止延迟显示
            d->DelayedAutoHideTimer.stop();
            break;
        case QEvent::Leave:
            // 如果自动隐藏容器可见，则设置延迟隐藏
            if (AutoHideContainer->isVisible())
            {
                d->DelayedAutoHideTab = AutoHideContainer->autoHideTab();
                d->DelayedAutoHideShow = false;
                d->DelayedAutoHideTimer.start();
            }
            break;
        default:
            break;
        }
        return;
    }
}
} // namespace ads

//---------------------------------------------------------------------------
// EOF DockContainerWidget.cpp
